#ifndef _PAGED_BLOCK_
#define _PAGED_BLOCK_

#include "Node.h"
#include "ForestLoader.h"
#include "FEngineType.h"
#include "PrimitiveLineList.h"
#include "AABB.h"

// Store the informations about one impostor's four vertices
struct QuadVertex
{
	FE_IMPOSTOR* vertex1;
	FE_IMPOSTOR* vertex2;
	FE_IMPOSTOR* vertex3;
	FE_IMPOSTOR* vertex4;
};

namespace FEngine
{
	/**
	 * Represent one page of the Forest Loader.
	 * Each object added to the ForestLoader is contained in a page.
	 * Each page mannage its list of objects and send them to the draw call if the page is visible.
	 * There is two type of object, the 3D object which are draw when they are close to the camera,
	 * and the impostor which are billboard tanking the place of the object when they are far from the camera.
	 */
	class PagedTreeBlock
	{

		public:

			/**
			 * Constructor.
			 * @param _minPoint Minimum point of the page (AABB).
			 * @param _maxPoint Maximum point of the page (AABB).
			 * @param _maxViewDistance View range of the object inside the block.
			 * @param _impostorApparitionDistance View range from wich the impostor are drawn.
			 */
			PagedTreeBlock(const Vector3& _minPoint, const Vector3& _maxPoint, float _maxViewDistance, float _impostorApparitionDistance);
			~PagedTreeBlock();
			
			/**
			 * Add one instance of the object to the scene.
			 * @param _pos Position of the object.
			 * @param _rot Rotation of the object.
			 * @param _sca Scale of the object.
			 * @param _sca Original scale of the impostor.
			 */
			void addObject(const Vector3& _pos, const Vector3& _rot, const Vector3& _sca, const Vector3& _impostorScale);

			/**
			 * Add one instance of the object to the scene.
			 * @param _worldMat World matrix of the object.
			 */
			void addObject(const Matrix4& _worldMat);
			
			bool isVisible() const;
			int	getNumberObject() const;
			int	getNumberVisibleObject() const;
			int	getNumberImpostor() const;
			int	getNumberVisibleImpostor() const;
			
			/**
			 * Add to the given list every instance's matrix of the page.
			 * @param _vectorObjectInstance Pointer to the vector storing every matrix.
			 */
			void getVectorVisibleObjectInstance(std::vector<Matrix4>* _vectorObjectInstance);
			
			/**
			 * Add to the given list every instance's vertices of the page.
			 * @param _vectorImpostorInstance Pointer to the vector storing every vertices.
			 */
			void getVectorVisibleImpostorInstance(std::vector<FE_IMPOSTOR*>* _vectorImpostorInstance);

			
			void update(double _elapsedTime);

			void _computeFrustumCulling();


		private:

			AABB*						mAABB;	// Define the limits of the page
			bool						mIsVIsible;
			
			float						mMaximumViewDistance;
			float						mMaximumViewDistanceSquared;
			float						mImpostorApparitionDistance;
			float						mImpostorApparitionDistanceSquared;
			
			std::vector<Matrix4>		mVectorObjectInstance;
			std::vector<Matrix4>		mVectorVisibleObjectInstance;
			
			std::vector<QuadVertex*>	mVectorImpostorInstance;
			std::vector<QuadVertex*>	mVectorVisibleImpostorInstance;

	};

} // namespace FEngine

#endif
